package com.ld.zookeeper.api;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * @author:ld
 * @create:2020-04-21 14:00
 * @description:
 */
public class ZookeeperExists {

    //连接对象
    private ZooKeeper zooKeeper;

    //连接地址
    private final String IP = "127.0.0.1:2181";

    private CountDownLatch countDownLatch = new CountDownLatch(1);

    /**
     * 开启连接
     */
    @Before
    public void befor() throws IOException, InterruptedException {
        //创建连接，因为是异步连接的，需要等待连接成功才能使用
        // arg1：连接地址
        // arg2：超时时间
        // arg3：自定义监视器
        zooKeeper = new ZooKeeper(IP, 5000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //连接成功
                if(Event.KeeperState.SyncConnected.equals(watchedEvent.getState())){
                    countDownLatch.countDown();
                    System.out.println("连接成功......");
                }else if(Event.KeeperState.Disconnected.equals(watchedEvent.getState())){
                    System.out.println("连接失败......");
                }else if(Event.KeeperState.AuthFailed.equals(watchedEvent.getState())){
                    System.out.println("用户认证失败......");
                }
            }
        });
        //等待连接成功
        countDownLatch.await();
    }

    /**
     * 关闭连接
     * @throws InterruptedException
     */
    @After
    public void after() throws InterruptedException {
        zooKeeper.close();
    }

    /**
     * 同步判断节点是否存在，使用连接器中的监视器
     */
    @Test
    public void exists1() throws KeeperException, InterruptedException {
        // arg1：节点路径
        // arg2：是否开启监听，false：不开启，true：开启
        Stat stat = zooKeeper.exists("/exists", false);
        if(stat == null)
            System.out.println("节点不存在......");
        else
            System.out.println(stat.getVersion());
    }

    /**
     * 同步判断节点是否存在，并且自定义监视器，监视器是一次性的
     *
     * 支持监控的事件
     *  NodeCreated
     *  NodeDeleted
     *  NodeDataChanged
     */
    @Test
    public void exists2() throws KeeperException, InterruptedException {
        Stat stat = zooKeeper.exists("/exists", new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //节点路径
                System.out.println("节点路径：" + watchedEvent.getPath());
                //事件类型
                System.out.println("事件类型：" + watchedEvent.getType());
            }
        });
        if(stat == null)
            System.out.println("节点不存在......");
        else
            System.out.println(stat.getVersion());
        Thread.sleep(Long.MAX_VALUE);
        System.out.println("结束");
    }

    /**
     * 异步判断节点是否存在，使用连接器中的监视器
     */
    @Test
    public void exists3() throws InterruptedException {
        zooKeeper.exists("/exists", false, new AsyncCallback.StatCallback() {
            @Override
            public void processResult(int i, String s, Object o, Stat stat) {
                //结果
                System.out.println("结果：" + i);
                //节点路径
                System.out.println("节点路径：" + s);
                //上下文对象
                System.out.println("上下文对象：" + o);
                //状态对象
                System.out.println(stat.getVersion());
            }
        },"I am context");
        Thread.sleep(Long.MAX_VALUE);
        System.out.println("结束");
    }

    /**
     * 异步判断节点是否存在，并且自定义监视器，监视器是一次性的
     */
    @Test
    public void exists4() throws InterruptedException {
        zooKeeper.exists("/exists", new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //节点路径
                System.out.println("节点路径：" + watchedEvent.getPath());
                //事件类型
                System.out.println("事件类型：" + watchedEvent.getType());
            }
        }, new AsyncCallback.StatCallback() {
            @Override
            public void processResult(int i, String s, Object o, Stat stat) {
                //结果
                System.out.println("结果：" + i);
                //节点路径
                System.out.println("节点路径：" + s);
                //上下文对象
                System.out.println("上下文对象：" + o);
                //状态对象
                System.out.println(stat.getVersion());
            }
        }, "I am context");
        Thread.sleep(Long.MAX_VALUE);
        System.out.println("结束");
    }

}
